-----------------------------------------------------------------------
-- File:        Zone.adb
-- Description: Provides zone acquiring and release functionality
--
-- Requires:    Io_Ports,Unsigned_Types,Raildefs,Dio192defs, Dda06defs,
--              Int32defs,Topolog2,Dio192_Blocks
--				
-- Author:     Ha Le
-----------------------------------------------------------------------
--with Ada.Text_Io, Ada.Integer_Text_Io;
--use Ada.Integer_Text_Io;
--with Simrail2;
with Io_Ports;
--with Swindows;
--use Swindows;
with Ada.Text_IO; --*
with Unsigned_Types;
use Unsigned_Types;  -- 1.8
with Raildefs,
   Dio192defs, Dda06defs, Int32defs;
use Raildefs;
with Topolog2;
use Topolog2;
--with Interrupt_Hdlr;
with Dio192_Blocks;

package body Zone is --PROTECTED

   --Declaring types
   type Zone_State is array (Topolog2.Zone_Id) of Boolean;
   type Zone_Owner is array (Topolog2.Zone_Id) of Train_Idx;
   type MaxTime is array (Topolog2.Zone_Id) of Natural;
   Max_Time : constant Natural := 30;


   --Protected Object Declaration
   protected Object is

      --Acquire a zone
      procedure Acquire_Zone (
            Success :    out Boolean;
            Train   : in     Raildefs.Train_Id;
            C       : in     Topolog2.Zone_Id);
      --Releasea zone
      procedure Release_Zone (
            Train : in     Raildefs. Train_Id;
            C     : in     Topolog2.Zone_Id);

   private
      --Private members
      Zone_Status:Zone_State:= (others => False);
      Owner: Zone_Owner:= (others => 0);
      Timeout : MaxTime := (others => Max_Time);

   end Object;

   --Protected Object Body
   protected body Object is

      --Acquire a Zone
      procedure Acquire_Zone (
            Success :    out Boolean;
            Train   : in     Raildefs.Train_Id;
            C       : in     Topolog2.Zone_Id) is
      begin
         if Timeout(C) = 0 or Zone_Status(C)=False or Owner(C) = Train then
            Success := True;
            Zone_Status(C):=True;
            Owner(C):=Train;
            Timeout(C) := Max_Time;
         else
            Timeout(C) :=  Timeout(C) -1;
            Success := False;
         end if;
         Ada.Text_Io.Put_Line("Acquiring Zone...."&C'Img&"Enquiring   "&Train'Img&"Owner..."&Owner(C)'Img&"Success "&Success'Img); --*
      end Acquire_Zone;

      --Release a Zone
      procedure Release_Zone (
            Train : in     Raildefs. Train_Id;
            C     : in     Topolog2.Zone_Id) is
      begin
         if(Train =Owner(C)) then
            Zone_Status(C):=False;
            Owner(C):=0;
         end if;
      end Release_Zone;

   end Object;

   --Public Procedures
   --Acquire a Zone
   procedure Acquire_Zone (
         Success :    out Boolean;
         Train   : in     Raildefs.Train_Id;
         B       : in     Topolog2.Zone_Id) is

   begin

      Object. Acquire_Zone (Success, Train, B);

   end Acquire_Zone;

   --Release a Zone
   procedure Release_Zone (
         Train : in     Raildefs. Train_Id;
         B     : in     Topolog2.Zone_Id) is

   begin
      Object. Release_Zone (Train,B);
   end Release_Zone;


end Zone;